//初始数据库结构
const dbData = [
	{
		dbName: "masterDB", //数据库名称
		version: 1, //数据库版本号,当结构发生变化时
		tables: [
			//表
			{
				name: "SYS_favorites", //表名称
				keyPath: "uid", //主键
				autoIncrement: false, //主键是否自增
				index: [
					//索引
					{
						name: "name_index", //索引名称
						key: "name", //索引key
					},
				],
			},
			{
				name: "SYS_keyword",
				keyPath: "id",
			},
		],
	},
	{
		dbName: "guestDB",
		version: 1,
		tables: [
			{
				name: "MY_demo",
				keyPath: "id",
			},
		],
	},
];

// 使用示例
// import DB from '@/utils/db'

// 初始化创建数据库 一般在项目启动时就执行了
// await DB.create()

// 打开某个数据库，返回数据库实例
// const database = await DB.open("dbName")

// 在打开的数据库中添加数据到tablenName表
// await database.add("tablenName", data)

// 查询
// await database.get("tablenName", key)

// 查询 根据索引
// await database.indexGet("tablenName", "indexName", indexVal)

// 修改
// await database.put("tablenName", data)

// 删除
// await database.delete("tablenName", key)

// 获取所有
// await database.getAll("tablenName")

// 清空某个表数据
// await database.clear("tablenName")

// 获取某个表信息
// database.getTable("tablenName")

// 获取所有表
// database.getTables()

// 关闭数据库连接
// database.close()

export default {
	//建立数据库，表，初始数据
	create() {
		var promiseArray = [];
		const addDB = (db) => {
			return new Promise((resolve, reject) => {
				const request = indexedDB.open(db.dbName, db.version);
				(request.onupgradeneeded = (e) => {
					const thisDB = e.target.result;
					db.tables.forEach((item) => {
						let table = null;
						if (thisDB.objectStoreNames.contains(item.name)) {
							//已存在表，删除旧index
							table = e.target.transaction.objectStore(item.name);
							table.indexNames.length > 0 &&
								table.indexNames.forEach((indexName) => {
									table.deleteIndex(indexName);
								});
						} else {
							//创建新的表
							table = thisDB.createObjectStore(item.name, {
								keyPath: item.keyPath,
								autoIncrement: item.autoIncrement,
							});
						}
						//建立index
						item.index &&
							item.index.forEach((ind) => {
								table.createIndex(ind.name, ind.key, {
									unique: false,
								});
							});
					});
				}),
					(request.onsuccess = (e) => {
						return resolve(e.target.result);
					});
				request.onerror = (e) => {
					return reject(e);
				};
			});
		};
		dbData.forEach((db) => {
			promiseArray.push(addDB(db));
		});
		return new Promise((resolve, reject) => {
			Promise.all(promiseArray)
				.then((e) => {
					resolve(e);
				})
				.catch((e) => {
					reject(e);
				});
		});
	},
	//所有数据库
	databases() {
		return indexedDB.databases();
	},
	//打开数据库
	open(dbName) {
		return new Promise((resolve, reject) => {
			const request = indexedDB.open(dbName);
			request.onsuccess = (e) => {
				const database = new this.database(e.target.result);
				resolve(database);
			};
			request.onerror = (e) => {
				reject(e);
			};
		});
	},
	//删除数据库
	deleteDB(dbName) {
		return indexedDB.deleteDatabase(dbName);
	},
	//数据库类
	database: function (IDBDatabase) {
		this.IDBDatabase = IDBDatabase;

		/**
		 * 添加行数据
		 * @param {string} tableName 表名
		 * @param {object} data 数据
		 * @returns {promise}
		 */
		this.add = (tableName, data) => {
			return new Promise((resolve, reject) => {
				const request = IDBDatabase.transaction(
					[tableName],
					"readwrite"
				)
					.objectStore(tableName)
					.add(data);
				request.onsuccess = (e) => {
					resolve(e);
				};
				request.onerror = (e) => {
					reject(e);
				};
			});
		};

		/**
		 * 修改行数据，未查询到就新增
		 * @param {string} tableName 表名
		 * @param {object} data 数据
		 * @returns {promise}
		 */
		this.put = (tableName, data) => {
			return new Promise((resolve, reject) => {
				const request = IDBDatabase.transaction(
					[tableName],
					"readwrite"
				)
					.objectStore(tableName)
					.put(data);
				request.onsuccess = (e) => {
					resolve(e);
				};
				request.onerror = (e) => {
					reject(e);
				};
			});
		};

		/**
		 * 删除行
		 * @param {string} tableName 表名
		 * @param {string} key 主键
		 * @returns {promise}
		 */
		this.delete = (tableName, key) => {
			return new Promise((resolve, reject) => {
				const request = IDBDatabase.transaction(
					[tableName],
					"readwrite"
				)
					.objectStore(tableName)
					.delete(key);
				request.onsuccess = (e) => {
					resolve(e);
				};
				request.onerror = (e) => {
					reject(e);
				};
			});
		};

		/**
		 * 根据主键获取行
		 * @param {string} tableName 表名
		 * @param {string} key 主键
		 * @returns {promise}
		 */
		this.get = (tableName, key) => {
			return new Promise((resolve, reject) => {
				const request = IDBDatabase.transaction(
					[tableName],
					"readwrite"
				)
					.objectStore(tableName)
					.get(key);
				request.onsuccess = () => {
					resolve(request.result || null);
				};
				request.onerror = (e) => {
					reject(e);
				};
			});
		};

		/**
		 * 根据索引获取行
		 * @param {string} tableName 表名
		 * @param {string} indexName 索引库名称
		 * @param {string} indexVal 索引值
		 * @returns {promise}
		 */
		this.indexGet = (tableName, indexName, indexVal) => {
			return new Promise((resolve, reject) => {
				const request = IDBDatabase.transaction(
					[tableName],
					"readwrite"
				)
					.objectStore(tableName)
					.index(indexName)
					.get(indexVal);
				request.onsuccess = () => {
					resolve(request.result || null);
				};
				request.onerror = (e) => {
					reject(e);
				};
			});
		};

		/**
		 * 获取所有行
		 * @param {string} tableName 表名
		 * @returns {promise}
		 */
		this.getAll = (tableName) => {
			return new Promise((resolve, reject) => {
				const request = IDBDatabase.transaction(
					[tableName],
					"readwrite"
				)
					.objectStore(tableName)
					.getAll();
				request.onsuccess = () => {
					resolve(request.result || null);
				};
				request.onerror = (e) => {
					reject(e);
				};
			});
		};

		/**
		 * 清空表
		 * @param {string} tableName 表名
		 * @returns {promise}
		 */
		this.clear = (tableName) => {
			return new Promise((resolve, reject) => {
				const request = IDBDatabase.transaction(
					[tableName],
					"readwrite"
				)
					.objectStore(tableName)
					.clear();
				request.onsuccess = (e) => {
					resolve(e);
				};
				request.onerror = (err) => {
					reject(err);
				};
			});
		};

		/**
		 * 获取表信息
		 * @returns {IDBObjectStore}
		 */
		this.getTable = (tableName) => {
			const request = IDBDatabase.transaction(
				[tableName],
				"readwrite"
			).objectStore(tableName);
			return request;
		};

		/**
		 * 获取所有的表
		 * @returns {[IDBObjectStore]}
		 */
		this.getTables = () => {
			const tables = [];
			for (let item of IDBDatabase.objectStoreNames) {
				tables.push(
					IDBDatabase.transaction([item], "readwrite").objectStore(
						item
					)
				);
			}
			return tables;
		};

		/**
		 * 关闭数据库连接
		 * @returns {}
		 */
		this.close = () => {
			return IDBDatabase.close();
		};
	},
};
